/*
 * File:   ServerStorageProtocol.h
 * Author: wilq
 *
 * Created on June 13, 2012, 7:40 PM
 */

#ifndef SERVERSTORAGEPROTOCOL_H
#define	SERVERSTORAGEPROTOCOL_H

#include "BaseServerProtocol.h"
#include "IStorageSync.h"

using namespace CSDatabaseLib;

typedef uint32_t THANDLE;

/**
 * Klasa obsługujące wysyłanie żadań do magazynu
 */
class ServerStorageProtocol : public virtual BaseServerProtocol {
public:
    /** 
	 * Konstruktor podstawowy 
	 * @param s wskaźnik na socket.
	 */
    ServerStorageProtocol(socket_ptr s);
    virtual ~ServerStorageProtocol();

    /**
     * Pobranie identyfikatora magazynu
     * @return identyfikator magazynu
     */
    inline uint32_t GetStorageId() {
        return connectedStorageId;
    }

    /**
     * Pobieranie informację o linku
     * @param link 
     * @param out_link
     * @param out_name
     * @return 
     */
    EType GetInfo(const std::string &link, std::string *out_link = NULL, std::string *out_name = NULL);
    
    /**
     * 
     * @param parentLink
     * @param name
     * @param out_link
     * @param out_name
     * @return 
     */
    EType GetInfo(const std::string &parentLink, const std::string &name, std::string *out_link = NULL, std::string *out_name = NULL);
    
    /**
     * Otwiera plik
     * @param link identyfikator pliku
     * @param options parametry otwarcia pliku
     * @return uchwyt do pliku
     */
    THANDLE FileOpen(const std::string &link, const std::string &options);
    
    /**
     * Otwiera plik 
     * @param parentlink identyfikator pliku w magazynie
     * @param name nazwa 
     * @param options opcję otwrcia
     * @return uchwyt do pliku
     */
    THANDLE FileOpen(const std::string &parentlink, const std::string &name, const std::string &options);
    
    /**
     * Zamyka plik
     * @param file uchwyt do pliku
     * @return status operacji
     */
    bool FileClose(THANDLE file);
    
    /**
     * Pobiera informację na temat pliku
     * @param file uchwyt do pliku
     * @param infoType 0 - rozmiar, 1 - czas, 2 - pozycja
     * @param outInfo informację o pliku
     * @return status operacji
     */
    bool FileInfo(THANDLE file, uint8_t infoType, uint64_t &outInfo);
    
    /**
     * Zmiana pozycji kursora w pliku
     * @param file uchwyt do pliku
     * @param position nowa pozycja kursora
     * @return status operacji
     */
    bool FileSeek(THANDLE file, int64_t position /*-1 for end*/);
    
    /**
     * Sprawdza czy pozycja kursora jest na końcu pliku
     * @param file uchwyt do pliku
     * @return status operacji
     */
    bool FileEof(THANDLE file);
    
    /**
     * Zapisuję dane do pliku
     * @param file uchwyt do pliku
     * @param size rozmiar buffora danych
     * @param data buffor z danymi do zapisu
     * @return status operacji
     */
    int32_t FileWrite(THANDLE file, uint32_t size, const uint8_t *data);
    
    /**
     * Odczytuję dane z pliku
     * @param file uchwyt do plikku
     * @param size rozmiar buffora danych do odczytu
     * @param data buffor na dane
     * @return 
     */
    int32_t FileRead(THANDLE file, uint32_t size, uint8_t *data);
    
    /**
     * Usuwa plik
     * @param link - identyfikator pliku
     * @return status operacji
     */
    int16_t FileDelete(const std::string &link);
    
    /**
     * Zmienia lokalizację pliku
     * @param link identyfikator pliku 
     * @param destinationFolderLink identyfikator katalogu do którego zostanie przeniesiony plik
     * @param newFileName nowa nazwa pliku
     * @param force wymuszenie
     * @return status operacji
     */
    int16_t FileMove(const std::string &link, const std::string &destinationFolderLink = "", const std::string &newFileName = "", bool force = false);
    
    /**
     * Kopiuję plik z jednej lokalizacji do drugiej.
     * @param link identyfikator pliku
     * @param destinationFolderLink identyfikator folderu do którego zostanie zapisane plik
     * @param newFileName nowa nazwa pliku
     * @param force wymuszenie
     * @return status operacji
     */
    int16_t FileCopy(const std::string &link, const std::string &destinationFolderLink = "", const std::string &newFileName = "", bool force = false);
    
    /**
     * Synchronizacja folderu
     * @param link identyfikator
     * @param recursive czy operacja ma być rekursywna
     * @return typ folderu
     */
    EType FolderSync(const std::string &link, bool recursive = false);
    
    /**
     * Tworzenie katalogu
     * @param link identyfikator katalogu
     * @param folderName nazwa katalogu
     * @return status operacji
     */
    bool FolderCreate(const std::string &link, const std::string &folderName);
    
    /**
     * Przenosi katalog z jednej lokalizacji do drugiej
     * @param link identyfikator folderu
     * @param destinationFolderLink identyfikator folderu do którego zostanie przeniesiony
     * @param newFolderName nowa nazwa folderu
     * @param force wymuszenie 
     * @return status operacji
     */
    int16_t FolderMove(const std::string &link, const std::string &destinationFolderLink = "", const std::string &newFolderName = "", bool force = false);
    
    /**
     * Kopiuję folder 
     * @param link identyfikator katalogu do kopiowania
     * @param destinationFolderLink identyfikator folderu do którego zostanie skopiowany orginalny katalog
     * @param newFolderName nowa nazwa katalogu
     * @param force wymuszenie
     * @return 
     */
    int16_t FolderCopy(const std::string &link, const std::string &destinationFolderLink = "", const std::string &newFolderName = "", bool force = false);
    
    /**
     * Usuwa folder
     * @param link identyfikator folderu
     * @return status operacji
     */
    int16_t FolderDelete(const std::string &link);
    
private:
    uint32_t connectedStorageId;

    /**
     * Obsługa autoryzacji magazynu
     * @param request pakiet z danymi
     */
    void OnStorageAuthorization(const NetworkPacket &request);

    /**
     * Obsługa żądania pobrania informacji o pliku
	 *
	 * Format pakietu:
	 *      string - link
     *       --- if exists:
     *       string - parent folder link
     *       string - filename
     *       S64 - size
     *       U64 - timestamp
     * @param request pakiet synchronizacyjny
     */
    void OnFileInfo(const NetworkPacket &request);

    /**
     * Obsługa żadania pobrania informacji o folderze
	 *
	 * Format pakietu:
	 *       string - link
     *        --- if exists:
     *        string - parent folder link
     *        string - folder name
	 *		  bool - folder sync
     * @param request pakiet synchronizacyjny
     */
    void OnFolderInfo(const NetworkPacket &request);
};

#endif	/* SERVERSTORAGEPROTOCOL_H */

